package com.yao.myioc.factory.support;

import com.yao.myioc.definition.BeanDefinition;
import com.yao.myioc.factory.BeanFactory;
import com.yao.myioc.factory.ListableBeanFactory;
import com.yao.myioc.registry.support.DefaultSingletonBenRegistry;

/**
 * 符合抽象模板设计模式的一个抽象类 抽象模板方法设计模式，由两个角色组成（父类和子类） 父类指定统一的处理步骤 子类负责特定步骤的细节实现
 * getBean + getSingleton
 * @author Henry Yao
 */
public abstract class AbstractBeanFactory extends DefaultSingletonBenRegistry implements BeanFactory {
    /**
     * 使用模板方法模式将bean的创建步骤固定下来
     *
     * @param beanName
     * @return
     */
    @Override
    public Object getBean(String beanName) {
        // 1.获取bean的定义信息
        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        if (beanDefinition == null) {
            System.out.println("未找到beanName=【" + beanName + "】的bean的定义信息");
            return null;
        }
        // 2.判断是不是单例bean
        if (beanDefinition.isSingleton()) {
            // 3、如果是单例bean尝试从缓存获取
            Object singleton = getSingleton(beanName);
            if (singleton == null) {
                // 3.2未获取到，先创建，再讲创建的对象加入缓存再返回
                Object bean = createBean(beanName, beanDefinition);
                addSingleton(beanName, bean);
                return bean;
            } else {
                // 3.1获取到直接返回
                return singleton;
            }
        }
        // 4、非单例bean直接创建
        return createBean(beanName, beanDefinition);
    }

    /**
     * 创建bean的实例，最后将会由子类实现，同时子类也会一并实现AutowiredCapableBeanFactory中的该方法
     * @param beanName
     * @param beanDefinition
     * @return
     */
    protected abstract Object createBean(String beanName, BeanDefinition beanDefinition);

    /**
     * 获取bean的定义信息，最后将会由子类实现，同时子类也会一并实现BeanDefinitionRegistry中的该方法
     *
     * @param name
     * @return
     */
    protected abstract BeanDefinition getBeanDefinition(String name);

}
